package team.you.change.util;

import org.apache.ibatis.session.SqlSession;
import org.junit.runner.RunWith;
import org.springframework.cglib.proxy.InvocationHandler;
import org.springframework.cglib.proxy.Proxy;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

import java.lang.reflect.Method;
import java.util.List;

/**
 * 对部分重复代码的提取
 * @author you
 */
@RunWith(SpringRunner.class)// SpringJUnit支持，由此引入Spring-Test框架支持！ 
@ContextConfiguration({"classpath*:mapper/*.xml","classpath:spring-mybatis.xml"})//用于加载bean
public class YouUtil {
    private static SqlSession sqlSession;

    public static void getSqlSession(){
//        sqlSession = sqlSessionFactory.openSession(true);
//        DefaultSqlSessionFactory dssf = new DefaultSqlSessionFactory();
//        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
//        try {
//            SqlSessionFactory sessionFactory = factoryBean.getObject();
//            sqlSession = sessionFactory.openSession(true);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
    }

    /**
     * 对分页参数进行计算
     * @param page 页码
     * @param limit 每页条数
     * @return sql语句中的第一个参数
     */
    public static Integer getPage(Integer page, Integer limit){
        if (page <= 0) {
            page = 1;
            page = (page - 1) * limit;
        } else page = (page - 1) * limit;
        return page;
    }
    /**
     * 对分页查询结果进行返回
     * @param result 返回工具类
     * @param datas 当前页数据列表
     * @param count 总数据条数
     * @param <T> 对于类的泛型
     * @return result
     */
    public static <T> Result setData(Result result,List<T> datas, Integer count){
        result.setData(datas);
        result.setCount(count);
        return result;
    }

    /**
     * 出现异常后处理
     * @param e 异常
     * @param result 返回工具类
     * @return result
     */
    public static Result setErrorMsg(Exception e, Result result){
        e.printStackTrace();
        result.setCode(500);
        result.setMsg("系统繁忙");
        return result;
    }

    /**
     * 出现sql错误时处理
     * @param result 返回工具类
     * @return result
     */
    public static Result setFlaseMsg(Result result){
        result.setCode(500);
        result.setMsg("操作出错");
        return result;
    }

    /**
     * 更新，删除，插入后结果判断处理 成功返回成功信息 失败返回错误信息
     * @param i 数据库返回的受影响行数
     * @param result 返回工具类
     * @return result
     */
    public static Result crudMsg(Integer i, Result result){
        if (i == 1) {
            result.setMsg("操作成功");
            return result;
        } else {
            return setFlaseMsg(result);
        }
    }

    /**
     * 根据id删除单条数据
     * @param t 泛型参数为对于XXMapper
     * @param id 删除数据的id
     * @param <T> 接收泛型
     * @return result公共返回类
     */
    public static <T> Result del(T t, Integer id){
//        Class<?> clazz = t.getClass(); //反射获取对象
//        Result result = new Result();
//        try {
//            Method method = clazz.getMethod("selectByPrimaryKey"); // 根据方法名获取方法
//            Object invoke = method.invoke(clazz); //执行方法， 可以加参数
//            if(invoke != null){
//                return YouUtil.crudMsg((Integer) clazz.getMethod("deleteByPrimaryKey").invoke(clazz, id), result);
//            }else {
//                result.setCode(500);
//                result.setMsg("该行不存在");
//                return result;
//            }
//        } catch (Exception e) {
//            return YouUtil.setErrorMsg(e, result);
//        }
        return YouUtil.del(t, id);
    }

    /**
     * 对于id为string的重载
     * @param t
     * @param id
     * @param <T>
     * @return
     */
    public static <T> Result del(T t, String id){
        Class<?> clazz = t.getClass(); //反射获取对象
        Object instance = Proxy.newProxyInstance(
                clazz.getClassLoader(),//类加载器
                new Class[] { clazz },//接口数组
                (InvocationHandler) new MyInvocationHandler(sqlSession.getMapper(clazz))//为接口实现的对应具体方法
        );//为接口实例化对象
        Result result = new Result();
        try {
//            Object mapper = sqlSession.getMapper(t.getClass());
            Method method = instance.getClass().getMethod("selectByPrimaryKey"); // 根据方法名获取方法
            Object invoke = method.invoke(instance); //执行方法， 可以加参数
            if(invoke != null){
                return YouUtil.crudMsg((Integer) instance.getClass().getMethod("deleteByPrimaryKey").invoke(instance, id), result);
            }else {
                result.setCode(500);
                result.setMsg("该行不存在");
                return result;
            }
        } catch (Exception e) {
            return YouUtil.setErrorMsg(e, result);
        }
    }

    /**
     * 根据id删除多条数据
     * @param t 泛型参数为对于XXMapper
     * @param ids id数组
     * @param <T> 泛型
     * @return result
     */
    public static <T> Result delete(T t, Integer[] ids){
//        Result result = new Result();
//        Class<?> clazz = t.getClass();
//        try {
//            Method method = clazz.getMethod("deleteByPrimaryKey");
//            for (int i = 0; i < ids.length; i++) {
//                method.invoke(clazz, ids[i]);
//            }
//            return result;
//        } catch (Exception e) {
//            return YouUtil.setErrorMsg(e, result);
//        }
        return YouUtil.delete(t, ids);
    }

    /**
     * 对于String的重载
     * @param t
     * @param ids
     * @param <T>
     * @return
     */
    public static <T> Result delete(T t, String[] ids){
        Result result = new Result();
        Class<?> clazz = t.getClass();
        try {
            Method method = clazz.getMethod("deleteByPrimaryKey");
            for (int i = 0; i < ids.length; i++) {
                method.invoke(clazz, ids[i]);
            }
            return result;
        } catch (Exception e) {
            return YouUtil.setErrorMsg(e, result);
        }
    }
}
